#!/usr/bin/env python
# encoding: utf-8
# @author: Lin Han
# @contact: voldemort22@126.com
# @file: utils.py
# @time: 2021/2/20 18:17
# @desc:
import getpass
import json
import os
import socket
import time
import uuid
from datetime import datetime
from typing import List, Dict, Union

import copy
import json5
from fastapi import UploadFile


def get_time():
    return time.strftime('%Y-%m-%d %H:%M', time.localtime(time.time()))


def compare_time(time_1: str, time_2: str) -> bool:
    """
    如果time_1比time_2晚，则返回True；否则返回False

    :param time_1:
    :param time_2:
    :return:
    """
    time_1 = datetime.strptime(time_1, "%Y-%m-%d %H:%M")
    time_2 = datetime.strptime(time_2, "%Y-%m-%d %H:%M")
    if time_1 > time_2:
        return True
    else:
        return False


def get_ip_name():
    user_name = getpass.getuser()  # 获取当前用户名
    # 获取本机电脑名
    myname = socket.getfqdn(socket.gethostname())
    # 获取本机ip
    myaddr = socket.gethostbyname(myname)
    return user_name, myaddr


def get_mac_address() -> str:
    mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
    return ":".join([mac[e:e + 2] for e in range(0, 11, 2)])


def read_json(json_file: Union[UploadFile, str]) -> Dict:
    """
    读取Json文件
    :param json_file: Json文件路径
    """
    if type(json_file) is str:
        if json_file.endswith('.json'):
            try:
                return json.load(open(json_file, encoding="utf-8", errors='ignore'))
            except ValueError:
                return json.load(open(json_file, encoding="gbk", errors='ignore'))
        else:
            try:
                return json5.load(open(json_file, encoding="utf-8", errors='ignore'))
            except ValueError:
                return json5.load(open(json_file, encoding="gbk", errors='ignore'))
    else:
        json5.load(json_file, encoding="utf-8")


def save_json(obj: Union[Dict, List], json_path: str):
    """
    保存为Json文件
    :param obj: python字典文件
    :param json_path: 保存地址
    """
    if json_path.endswith('.json'):
        with open(json_path, "w", encoding="utf-8") as f:
            json.dump(obj, f, ensure_ascii=False, indent=4)
    else:
        with open(json_path, "w", encoding="utf-8") as f:
            json5.dump(obj, f, ensure_ascii=False, indent=4)


USERNAME, IP_ADDRESS = get_ip_name()

MAC = get_mac_address()


def generate_24_length_uuid():
    """
    使用uuid.uuid1()来生成string，扣除-后还有32位，其中最后的12位是16进制的mac地址，先将其转化为10进制的数字字符串，再取最后4位，
    再和uuid_string前面的20位拼接起来，即可。

    """
    uuid_string = str(uuid.uuid1()).replace("-", "")
    last_12_uuid_string = uuid_string[-12:]
    hex_uuid_string = str(int(last_12_uuid_string, 16))[:4]
    return uuid_string[:-12] + hex_uuid_string


def convert_data_group(group: List[dict]):
    """
    输入完整的json对象的列表，得到新形式的数据列表。

    :param group: 为一堆json数据的列表
    :return:
    """
    new_group = []
    for index, i in enumerate(group):
        TIME = get_time()
        item = dict()
        # Group从03开始算， Part从04开始算，是这样对吧？
        item['number'] = str(2021030000000001 + index)
        item['name'] = i['name']
        item['version'] = i['version'] if 'version' in i.keys() else ''
        item['CGuid'] = generate_24_length_uuid()
        item['CIp'] = IP_ADDRESS
        # 这个mac地址是用uuid的最后12位是mac地址的方法来生成的，不确定是不是对的，因为我的主机居然正好是010101010000
        item['CMac'] = MAC
        item['CUser'] = USERNAME
        item['time'] = TIME
        item['Data'] = i['data']
        # 有些数据的desc字段为空，想办法使其变成空值
        item['desc'] = i['desc'] if 'desc' in i.keys() else ''

        new_group.append(item)

    return new_group


def convert_data_part(part: List[dict]):
    """
    输入完整的json对象的列表，得到新形式的数据列表。

    :param part: 为一堆json数据的列表
    :return:
    """
    new_part = []
    for index, i in enumerate(part):
        TIME = get_time()
        item = dict()
        # Group从03开始算， Part从04开始算，是这样对吧？
        item['number'] = str(2021040000000001 + index)
        item['name'] = i['name']
        item['version'] = i['version'] if 'version' in i.keys() else ''
        item['CGuid'] = generate_24_length_uuid()
        item['CIp'] = IP_ADDRESS
        # 这个mac地址是用uuid的最后12位是mac地址的方法来生成的，不确定是不是对的，因为我的主机居然正好是010101010000
        item['CMac'] = MAC
        item['CUser'] = USERNAME
        item['time'] = TIME
        item['Data'] = i['data']
        # 有些数据的desc字段为空，想办法使其变成空值
        item['desc'] = i['desc'] if 'desc' in i.keys() else ''

        new_part.append(item)

    return new_part


def filter_part(part: List[dict], value: str, key: str = 'name') -> List[dict]:
    """
    把输入的字典的列表中每个元素，根据特定的键（默认为'name'）是否为特定的值来匹配，返回所有匹配的元素
    :param part:
    :param key:
    :param value:
    :return:
    """
    return_list = []
    for i in part:
        if i[key] == value:
            return_list.append(i)
    return return_list


def get_filtered_part_number(part: List[dict], value: str, key: str = 'name') -> List[str]:
    """
    把输入的字典的列表中每个元素，根据特定的键（默认为'name'）是否为特定的值来匹配，返回所有匹配的元素里的'number'键的值的列表
    :param part:
    :param value:
    :param key:
    :return:
    """
    filtered_list = filter_part(part, value, key)
    return [i['number'] for i in filtered_list]


def transfer_clamp_t(clamp_t: Dict) -> Dict:
    """
    输入原来的clamp_t数据，返回新格式的clamp_t数据

    :param clamp_t:
    """
    clampModel = {}
    clampModel["number"] = clamp_t["number"]
    clampModel["CUser"] = clamp_t["CUser"]
    clampModel["WorkPieceCatPartAddress"] = "暂无OSS地址"
    clampModel["ClampCatPartAddress"] = "暂无OSS地址"
    clampModel["WorkPieceCatPartMD5"] = "暂无MD5值"
    clampModel["ClampCatPartMD5"] = "暂无MD5值"
    clampModel["isFeature"] = clamp_t["isFeature"]
    clampModel["isFlag"] = clamp_t["isFlag"]
    clampModel["name"] = clamp_t["name"]
    # clampModel["time"] = datetime.strptime(clamp_t["time"], '%Y-%m-%d %H:%M')
    clampModel["time"] = clamp_t["time"]
    clampModel["tag"] = clamp_t["tag"]

    return clampModel


def transfer_part(part: Dict) -> Dict:
    """

    :param part:
    """
    partModel = {}
    partModel["number"] = part["number"]
    partModel["ClampNumber"] = "暂无父夹具id，请查询index表"
    partModel["PartCatPartAddress"] = "暂无OSS地址"
    partModel["PartCatPartMD5"] = "暂无MD5值"
    partModel["CUser"] = part["CUser"]
    partModel["isFeature"] = part["isFeature"]
    partModel["isFlag"] = part["isFlag"]
    partModel["name"] = part["name"]
    partModel["time"] = part["time"]
    partModel["tag"] = part["tag"]

    return partModel


def create_folder() -> str:
    """

    :return: 返回创建的文件夹路径
    """
    # 把文件暂存到本地，保存的文件名为temp_data/年/月/日/时/分/秒/文件名
    folder = f"temp_data/{datetime.today().year}/{datetime.today().month}/{datetime.today().day}/{datetime.today().hour}/{datetime.today().minute}/{datetime.today().second}"
    # 若文件夹不存在则创建
    if not os.path.exists(folder):
        os.makedirs(folder)
    return folder


def create_folder_including_workpiece() -> str:
    """

    :return: 返回创建的文件夹路径
    """
    # 把文件暂存到本地，保存的文件名为temp_data/年/月/日/时/分/秒/文件名
    folder = f"temp_data/{datetime.today().year}/{datetime.today().month}/{datetime.today().day}/{datetime.today().hour}/{datetime.today().minute}/{datetime.today().second}/workpiece"
    # 若文件夹不存在则创建
    if not os.path.exists(folder):
        os.makedirs(folder)
    return folder


def generate_filename(folder: str, file: UploadFile) -> str:
    """
    生成完整的文件名。

    :param folder:
    :param file:
    :return:
    """
    return f"{folder}/{file.filename}"


def write_file(file_path: str, file: UploadFile):
    """
    把接收到的UploadFile对象写入文件

    :param file_path:
    :param file:
    """
    with open(file_path, 'wb') as out_file:
        content = file.file.read()  # async read
        out_file.write(content)


def is_contained_by_another_list(list_1: list, list_2: list) -> bool:
    copied_list_2 = copy.deepcopy(list_2)

    for i in list_1:

        if i in copied_list_2:
            copied_list_2.remove(i)
        else:
            return False
    return True


if __name__ == '__main__':
    q = ['支撑', '定位']
    r = ['夹紧', '支撑', '定位']

    print(is_contained_by_another_list(q, r))
    print(q)
    print(r)
